home *** CD-ROM | disk | FTP | other *** search
/ Windows News 2010 Summer - Disc 1 / WN_Ete2010_CD1.iso / Onglet5 / Weezo / Weezo setup.exe / {code_appDir} / www / res / administration / std / stats.php < prev    next >
PHP Script  |  2010-05-19  |  68KB  |  1,505 lines

  1. <?php
  2. /**
  3.  * Site access statistics and history (V1.2.0+)
  4.  *
  5.  * this script is included by /administration/std/index.php or /local/showStats.php or /local/showHistory.php and shouldn't be directly called
  6.  *
  7.  * $displayType: history | stats
  8.  * $infoType: type of info displayed.
  9.  *                 stats: synth (graphs) | details (list of connections grouped by IP)
  10.  *                 history: single (single selected connection) | list (all connections in given time interval)
  11.  *
  12.  * PHP version 5
  13.  *
  14.  * LICENSE: This source file is subject to version 3.0 of the PHP license
  15.  * that is available through the world-wide-web at the following URI:
  16.  * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  17.  * the PHP License and are unable to obtain it through the web, please
  18.  * send a note to license@php.net so we can mail you a copy immediately.
  19.  *
  20.  * @category   NA
  21.  * @package    NA
  22.  * @author     Nicolas Bruley / Peer 2 World <contact@weezo.net>
  23.  * @copyright  2005-2009 Nicolas Bruley / Peer 2 World
  24.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  25.  * @version    CVS: $Id:$
  26.  * @link       http://www.weezo.net
  27.  * @since      File available since Release 1.0.0
  28.  */
  29.  
  30. define('MONITOR_LAST_VIEWED_FILE_INTERVAL',2000); // Interval (ms) for update of last viewed file thumnail (single history)
  31. define('STATS_MAX_THUMBNAIL_WIDTH',160); // Left panel thumbnail max width, file info thumbnail max width
  32. define('STATS_MAX_THUMBNAIL_HEIGHT',120); // Left panel thumbnail max height, file info thumbnail max height
  33. $_ENV['colorPath']=array(array(150,100,160),array(250,100,250),array(250,125,0),array(50,50,250),array(50,250,50),array(250,50,50),array(0,250,250),array(255,0,0),array(255,255,0)); // Color path used for graphs coloration (linear interpolation between dots)
  34.  
  35.  
  36. /**
  37.  * @desc set interval and localhost condition on a request on connection and resAccess tables
  38.  *
  39.  * @param string $query : SQL query
  40.  * @param integer $ts : "from" timestamp
  41.  * @param string $interval  : interval length : 'month', 'week' or 'day'
  42.  * @param string $groupBy : GROUP BY condition : 'day', 'hour', 'no'
  43.  */
  44. function createView1($ts, $ets, $showLocalhost=false){
  45.     global $db;
  46.     $query ="CREATE TEMP VIEW baseView AS SELECT connection.id, connection.ip, connection.hostname, connection.pseudo, connection.ts, connection.accountId, Sum(connection.duration) AS totalDuration, resAccess.resourceId, Sum(resAccess.pages) AS nbPages ";
  47.     $query.="FROM connection LEFT JOIN resAccess ON connection.id = resAccess.connectionId  WHERE ";
  48.  
  49.     if(!$showLocalhost) $query.="connection.ip!='127.0.0.1' AND ";
  50.     $query.="connection.ts>='".$ts."' AND connection.ts<='".$ets."' ";
  51.     $query.=" GROUP BY connection.ip, connection.ts, connection.accountId, resAccess.resourceId";
  52.     sqlite_query($query, $db);
  53. }
  54.  
  55. /**
  56.  * @desc set interval and localhost condition on a request on connection and resAccess tables
  57.  *
  58.  * @param string $query : SQL query
  59.  * @param integer $ts : "from" timestamp
  60.  * @param string $interval  : interval length : 'month', 'week' or 'day'
  61.  * @param string $groupBy : GROUP BY condition : 'day', 'hour', 'no'
  62.  */
  63. function createViewHistory($ts, $ets, $showLocalhost=false){
  64.     global $db;
  65.     $query ="CREATE TEMP VIEW baseView AS SELECT connection.id, connection.ip, connection.hostname, connection.pseudo, connection.ts, connection.accountId, Sum(connection.duration) AS totalDuration, resAccess.resourceId, Sum(resAccess.pages) AS nbPages ";
  66.     $query.="FROM connection LEFT OUTER JOIN resAccess ON connection.id = resAccess.connectionId  WHERE ";
  67.  
  68.     if(!$showLocalhost) $query.="connection.ip!='127.0.0.1' AND ";
  69.     $query.="connection.ts>='".$ts."' AND connection.ts<='".$ets."' ";
  70.     $query.=" GROUP BY connection.ip, connection.ts, connection.accountId, resAccess.resourceId";
  71.     sqlite_query($query, $db);
  72. }
  73.  
  74. /**
  75.  * @desc set interval and localhost condition on a request on connection and resAccess tables
  76.  *
  77.  * @param string $query : SQL query
  78.  * @param integer $ts : "from" timestamp
  79.  * @param string $interval  : interval length : 'month', 'week' or 'day'
  80.  * @param string $groupBy : GROUP BY condition : 'day', 'hour', 'no'
  81.  */
  82. function createViewDetail($connectionId){
  83.     global $db;
  84.     $query ="CREATE TEMP VIEW baseView AS SELECT connection.id, connection.ip, connection.hostname, connection.pseudo, connection.ts, connection.accountId, Sum(connection.duration) AS totalDuration, resAccess.resourceId, Sum(resAccess.pages) AS nbPages ";
  85.     $query.="FROM connection LEFT OUTER JOIN resAccess ON connection.id = resAccess.connectionId  WHERE connection.id = ".$connectionId;
  86.     $query.=" GROUP BY connection.ip, connection.ts, connection.accountId, resAccess.resourceId";
  87.     sqlite_query($query, $db);
  88. }
  89.  
  90. /**
  91.  * @desc set interval and localhost condition on a request on connection table
  92.  *
  93.  * @param string $query : SQL query
  94.  * @param integer $ts : "from" timestamp
  95.  * @param string $interval  : interval length : 'month', 'week' or 'day'
  96.  * @param string $groupBy : GROUP BY condition : 'day', 'hour', 'no'
  97.  */
  98. function createView2($ts, $ets, $showLocalhost=false){
  99.     global $db;
  100.     $query ="CREATE TEMP VIEW baseView AS SELECT * FROM connection WHERE ";
  101.     if(!$showLocalhost) $query.="connection.ip!='127.0.0.1' AND ";
  102.     $query.="connection.ts>='".$ts."' AND connection.ts<='".$ets."' ";
  103.     sqlite_query($query, $db);
  104. }
  105.  
  106. function array_plus($a,$b){return $a+$b;}
  107.  
  108. function yMax($nb){
  109.     if($nb<5) return 5;
  110.     $round=max(5,5*(pow(10,floor(log10($nb))-1)));
  111.     return $res=ceil($nb/$round)*$round;
  112. }
  113.  
  114. function truncateCaption($capt,$nb){
  115.     if(strlen($capt)>$nb) return substr($capt,0,$nb-3).'...'; else return $capt;
  116. }
  117.  
  118. /**
  119.  * @desc draw connections by account bar graph
  120.  *
  121.  * @param integer $intStart : start timestamp
  122.  * @param integer $intEnd : end timestamp
  123.  * @param string $intLength : length of interval (day, week, month)
  124.  * @param boolean $showLocalhost : show localhost connections
  125.  */
  126. function drawConnections($intStart, $intEnd, $intLength, $showLocalhost){
  127.     global $db;
  128.  
  129.     if($intLength=='all'){
  130.         if(($intEnd-$intStart)>24*31*24*3600) {
  131.             $intStep='year';
  132.             $intStart=mktime(0,0,1,1,1,date('Y',$intStart));
  133.         }
  134.         elseif(($intEnd-$intStart)>4*31*24*3600) {
  135.             $intStep='month';
  136.             $intStart=mktime(0,0,1,date('m',$intStart),1,date('Y',$intStart));
  137.         }
  138.         elseif(($intEnd-$intStart)>31*24*3600){
  139.             $intStep='week';
  140.         }
  141.         else $intStep='day';
  142.     }
  143.     elseif($intLength=='week' || $intLength=='month') $intStep='day';
  144.  
  145.     // Create view according to defined period and other options
  146.     createView2($intStart,$intEnd,$showLocalhost);
  147.  
  148.     if($showLocalhost=='1') $showLocalhost=true; else $showLocalhost=false;
  149.  
  150.     // Graph array
  151.     $xValues=array();
  152.     $t=$intStart;
  153.     while ($t<=$intEnd) {
  154.         if($intStep=='day'){
  155.             $xValues[date('Y-m-d',$t)]=cfUTF8Encode(date(cfCaption('_DATE_FORMAT'),$t));
  156.             $t+=24*3600;
  157.             $sqlStep='%Y-%m-%d';
  158.         }
  159.         elseif($intStep=='week'){
  160.             $xValues[date('Y-W',$t)]=cfUTF8Encode(strftime(cfCaption('calWeekShort'),$t));
  161.             $t+=7*24*3600;
  162.             $sqlStep='%Y-%W';
  163.         }
  164.         elseif($intStep=='month'){
  165.             $xValues[date('Y-m',$t)]=cfUTF8Encode(strftime('%b %Y',$t));
  166.             $t+=date('t',$t)*24*3600;
  167.             $sqlStep='%Y-%m';
  168.         }
  169.         else{
  170.             $xValues[date('Y',$t)]=cfUTF8Encode(strftime('%Y',$t));
  171.             $t=mktime(0,0,1,1,1,date('Y',$t)+1);
  172.             $sqlStep='%Y';
  173.         }
  174.     }
  175.  
  176.     // Db request
  177.     $result=sqlite_array_query($db,"SELECT strftime('".$sqlStep."',ts,'unixepoch') AS dte,Count(ip) AS cnt, accountId FROM baseView GROUP BY strftime('".$sqlStep."',baseView.ts,'unixepoch'),accountId",SQLITE_ASSOC);
  178.  
  179.     $accounts=sqlite_array_query($db,"SELECT id,name FROM account",SQLITE_ASSOC);
  180.     foreach ($accounts as $key=>$value){
  181.         $found=false;
  182.         foreach ($result as $value2){
  183.             if($value2['accountId']==$value['id']){
  184.                 $found=true;
  185.                 break;
  186.             }
  187.         }
  188.         if($found){
  189.             $accountsNames[$value['id']]=$value['name'];
  190.             $accountsValues[$value['id']]=array_pad(array(),count($xValues),0);
  191.         }
  192.     }
  193.     unset($accounts);
  194.     if(!isset($accountsNames)) {
  195.         $accountsNames=array('void'=>'void');
  196.         $accountsValues['void']=array_pad(array(),count($xValues),0);
  197.     }
  198.     $datesList=array_flip(array_keys($xValues));
  199.  
  200.     // Fill accountsValues array with $result content
  201.     foreach ($result as $value)    if($value['accountId']) @$accountsValues[$value['accountId']][$datesList[$value['dte']]]+=$value['cnt'];
  202.     // Sum values for bar graph
  203.     foreach ($accountsNames as $key=>$value) {
  204.         if(isset($prevKey)) $accountsValues[$key]=array_map('array_plus',$accountsValues[$key],$accountsValues[$prevKey]);
  205.         $prevKey=$key;
  206.     }
  207.  
  208.     dbCloseDB();
  209.     require_once INCLUDE_DIR."/artichow/BarPlot.class.php";
  210.  
  211.     $graph = new Graph(400, 350);
  212.     $graph->setAntiAliasing(TRUE);
  213.     $graph->title->setFont(new Tuffy(12));
  214.  
  215.     $nb=0;
  216.     foreach (array_reverse($accountsNames,true) as $key=>$value) {
  217.         $plot = new BarPlot($accountsValues[$key]);
  218.         $plot->grid->setBackgroundColor(new Color(0, 240, 240,100));
  219.  
  220.         // compute bar color
  221.         $cpi=2;
  222.         $bottom=min(floor($nb/$cpi),count($_ENV['colorPath'])-2);
  223.         $r=floor(($_ENV['colorPath'][$bottom][0]+($nb-$cpi*$bottom)*($_ENV['colorPath'][$bottom+1][0]-$_ENV['colorPath'][$bottom][0])/($cpi+1)));
  224.         $g=floor(($_ENV['colorPath'][$bottom][1]+($nb-$cpi*$bottom)*($_ENV['colorPath'][$bottom+1][1]-$_ENV['colorPath'][$bottom][1])/($cpi+1)));
  225.         $b=floor(($_ENV['colorPath'][$bottom][2]+($nb-$cpi*$bottom)*($_ENV['colorPath'][$bottom+1][2]-$_ENV['colorPath'][$bottom][2])/($cpi+1)));
  226.  
  227.         $color=new Color($r,$g,$b,0);
  228.  
  229.         $colors[]=$color;
  230.         $plot->setBarColor($color);
  231.         $graph->add($plot);
  232.  
  233.         if(!isset($axisDrawn)){
  234.             $plot->setBackgroundGradient(new LinearGradient(new Color(230, 230, 250),new Color(255, 255, 255),0));
  235.             $xPlotLabel=array_values($accountsValues[$key]);foreach ($xPlotLabel as $k=>$v) if($v==0) $xPlotLabel[$k]='';
  236.             $plot->xAxis->setLabelText(array_values($xValues));
  237.             $plot->xAxis->setLabelAngle(90);
  238.             $plot->label->set($xPlotLabel);
  239.             $plot->label->move(0, -10);
  240.             $plot->setYMin(0);
  241.             $yMax=yMax($plot->getYMax());
  242.  
  243.             $graph->title->set(cfCaption('calBarPlotTitle').' '.cfCaption('calTotal',array_sum($accountsValues[$key])));
  244.  
  245.             $axisDrawn=true;
  246.         }
  247.         else{
  248.             $plot->yAxis->hide(true);
  249.             $plot->xAxis->hide(true);
  250.             $plot->grid->hide(true);
  251.             $plot->setYMin(0);
  252.         }
  253.         $plot->setPadding(20, 80, 50, 60);
  254.         $plot->setYMax($yMax);
  255.         $nb++;
  256.     }
  257.  
  258.     require_once INCLUDE_DIR."/artichow/Pie.class.php";
  259.  
  260.     $values = array_pad(array(),count($accountsNames),1);
  261.  
  262.     $plot = new Pie($values, $colors);
  263.  
  264.     $plot->setCenter(0.4, 0.55);
  265.     $plot->setSize(0.7, 0.6);
  266.     $plot->setPadding(-400, 400, NULL, 60);
  267.  
  268.     $plot->setLegend(array_reverse(array_values($accountsNames)));
  269.     //$plot->legend->setBackgroundColor(new Color(255, 255, 255,125));
  270.  
  271.     $plot->legend->setPosition(1.3);
  272.     $plot->legend->shadow->setSize(0);
  273.  
  274.     $graph->add($plot);
  275.  
  276.     $graph->draw();
  277.     exit;
  278. }
  279.  
  280. /**
  281.  * @desc draw unique visitors by account pie
  282.  *
  283.  * @param integer $intStart : start timestamp
  284.  * @param integer $intEnd : end timestamp
  285.  * @param string $intLength : length of interval (day, week, month)
  286.  * @param boolean $showLocalhost : show localhost connections
  287.  */
  288. function drawVisitors($intStart, $intEnd, $intLength, $showLocalhost){
  289.     global $db;
  290.  
  291.     if($showLocalhost=='1') $showLocalhost=true; else $showLocalhost=false;
  292.  
  293.     // Create view according to defined period and other options
  294.     createView2($intStart,$intEnd,$showLocalhost);
  295.  
  296.     // Db requests
  297.     $result=sqlite_array_query($db,"SELECT ts,ip FROM baseView",SQLITE_ASSOC);
  298.  
  299.     $tmpFirstVisit=sqlite_array_query($db,"SELECT ip,min(ts) AS first FROM connection GROUP BY ip",SQLITE_ASSOC);
  300.     $firstVisit=array();foreach ($tmpFirstVisit as $value) $firstVisit[$value['ip']]=$value['first'];
  301.     unset($tmpFirstVisit);
  302.  
  303.     $first=0;$returning=0;
  304.     foreach ($result as $value){
  305.         if($firstVisit[$value['ip']]==$value['ts']) $first++; else $returning++;
  306.     }
  307.     dbCloseDB();
  308.     require_once INCLUDE_DIR."/artichow/Pie.class.php";
  309.     $graph = new Graph(350,350);
  310.  
  311.     //$graph->setAntiAliasing(TRUE);
  312.     $graph->title->set(cfCaption('calBarPieTitle'));
  313.     $graph->title->setFont(new Tuffy(12));
  314.  
  315.     $graph->setBackgroundGradient(new LinearGradient(new Color(230, 230, 250),new Color(255, 255, 255),0));
  316.  
  317.     if($first+$returning){
  318.         $plot = new Pie(array($first, $returning), Pie::AQUA);
  319.         $plot->setCenter(0.45, 0.49);
  320.         $plot->setSize(0.8, 0.8);
  321.         $plot->set3D(20);
  322.         $plot->explode(array(0 => 30));
  323.         $plot->setStartAngle(320);
  324.  
  325.         $plot->setLegend(array(cfCaption('calBarPieFirst').' ('.$first.')',cfCaption('calBarPieReturning').' ('.$returning.')'));
  326.         //$plot->legend->setBackgroundColor(new Color(255, 255, 255,125));
  327.         $plot->legend->setPosition(1.15,1);
  328.         $plot->legend->shadow->setSize(0);
  329.  
  330.         $graph->add($plot);
  331.     }
  332.     $graph->draw();
  333.     exit;
  334. }
  335.  
  336. /**
  337.  * @desc draw unique visitors by account pie
  338.  *
  339.  * @param integer $intStart : start timestamp
  340.  * @param integer $intEnd : end timestamp
  341.  * @param string $intLength : length of interval (day, week, month)
  342.  * @param boolean $showLocalhost : show localhost connections
  343.  */
  344. function drawResources($intStart, $intEnd, $intLength, $showLocalhost){
  345.     global $db;
  346.     if($showLocalhost=='1') $showLocalhost=true; else $showLocalhost=false;
  347.  
  348.     // Create view according to defined period and other options
  349.     createView1($intStart,$intEnd,$showLocalhost);
  350.  
  351.     // Db requests
  352.     $accessedResources=array();
  353.     foreach (sqlite_array_query($db,"SELECT resourceId, sum(nbPages) AS nbPages FROM baseView GROUP BY resourceId",SQLITE_ASSOC) as $value)
  354.         if($value['resourceId']) $accessedResources[$value['resourceId']]=$value['nbPages'];
  355.  
  356.     $resourceNames=array();
  357.     foreach(sqlite_array_query($db,"SELECT * FROM resource",SQLITE_ASSOC) as $value)
  358.         $resourceNames[$value['id']]=$value['name'];
  359.  
  360.     $resources=array();
  361.     $nb=0;
  362.  
  363.     // Required for Color class
  364.     require_once INCLUDE_DIR."/artichow/BarPlot.class.php";
  365.  
  366.     $colors=array();
  367.     foreach ($accessedResources as $key=>$value)
  368.         if(isset($resourceNames[$key])) {
  369.             $resources[$key]=(truncateCaption($resourceNames[$key],15)).'('.$value.')';
  370. /*
  371.             $bottom=min(floor($nb/3),count($_ENV['colorPath'])-2);
  372.             $r=floor(($_ENV['colorPath'][$bottom][0]+($nb-3*$bottom)*($_ENV['colorPath'][$bottom+1][0]-$_ENV['colorPath'][$bottom][0])/4));
  373.             $g=floor(($_ENV['colorPath'][$bottom][1]+($nb-3*$bottom)*($_ENV['colorPath'][$bottom+1][1]-$_ENV['colorPath'][$bottom][1])/4));
  374.             $b=floor(($_ENV['colorPath'][$bottom][2]+($nb-3*$bottom)*($_ENV['colorPath'][$bottom+1][2]-$_ENV['colorPath'][$bottom][2])/4));
  375. */
  376.             $cpi=2;
  377.             $bottom=min(floor($nb/$cpi),count($_ENV['colorPath'])-2);
  378.             $r=floor(($_ENV['colorPath'][$bottom][0]+($nb-$cpi*$bottom)*($_ENV['colorPath'][$bottom+1][0]-$_ENV['colorPath'][$bottom][0])/($cpi+1)));
  379.             $g=floor(($_ENV['colorPath'][$bottom][1]+($nb-$cpi*$bottom)*($_ENV['colorPath'][$bottom+1][1]-$_ENV['colorPath'][$bottom][1])/($cpi+1)));
  380.             $b=floor(($_ENV['colorPath'][$bottom][2]+($nb-$cpi*$bottom)*($_ENV['colorPath'][$bottom+1][2]-$_ENV['colorPath'][$bottom][2])/($cpi+1)));
  381.             $colors[]=new Color($r,$g,$b,0);
  382.             $nb++;
  383.         }
  384.  
  385.     dbCloseDB();
  386.     require_once INCLUDE_DIR."/artichow/Pie.class.php";
  387.     $graph = new Graph(400,350);
  388.  
  389.     //$graph->setAntiAliasing(TRUE);
  390.     $graph->title->set(cfCaption('calResourcePieTitle').' '.cfCaption('calTotal',array_sum($accessedResources)));
  391.     $graph->title->setFont(new Tuffy(12));
  392.  
  393.     $graph->setBackgroundGradient(new LinearGradient(new Color(230, 230, 250),new Color(255, 255, 255),0));
  394.  
  395.     if(count($accessedResources)){
  396.         $plot = new Pie(array_values($accessedResources), $colors);
  397.         $plot->setCenter(0.4, 0.60);
  398.         $plot->setSize(0.7, 0.7);
  399.         $plot->set3D(20);
  400.         $plot->setLabelMinimum(1);
  401.         $plot->setStartAngle(200);
  402.  
  403.         $plot->setLegend(array_values($resources));
  404.         //$plot->legend->setBackgroundColor(new Color(255, 255, 255,125));
  405.         $plot->legend->setPosition(1.3,0.15);
  406.         $plot->legend->shadow->setSize(0);
  407.         $graph->add($plot);
  408.     }
  409.     $graph->draw();
  410.     exit;
  411. }
  412.  
  413.  
  414. /*
  415.  * Verify access rights
  416. */
  417. if(!isset($_ENV['configurationEnvironment'])) $_ENV['configurationEnvironment']='browser';
  418. if(($_SERVER['REMOTE_ADDR']=='127.0.0.1' && cfIsInApp()) ||
  419.     (cfUGetVar('administrator')==true && cfGGetVar('remoteAdministrationAuthorized'))){}
  420. else
  421.     outDisplayErrorPage(cfcaption('errorRemoteAdministrationNotAuthorized'));
  422.  
  423. require_once(INCLUDE_DIR.'databaseFunctions.php');
  424.  
  425. // Open stats database
  426. $db=dbOpenDB();
  427.  
  428. // Select history or statistics
  429. if(!isset($displayType)){
  430.     if(basename($_SERVER['SCRIPT_NAME'])=='showStats.php') $displayType='stats'; else $displayType='history';
  431. }
  432.  
  433. /*
  434.  ***************************************************************************************************************************
  435.  * Init default data
  436.  ***************************************************************************************************************************
  437.  */
  438. $selectedMonth = mktime(0,0,1,date('n'),1,date('Y'));
  439. $intStart = mktime(0,0,1,date('n',time()-6*24*3600),date('j',time()-6*24*3600),date('Y',time()-6*24*3600));
  440. $intLength ='week';
  441. if(!isset($infoType)) $infoType = 'synth'; // Initialize $infoType for stats display
  442.  
  443. if(cfIsResource()){
  444.     cfRInitVar('showLocalhost',true);
  445.     $showLocalhost = cfRGetVar('showLocalhost');
  446. }
  447. else{
  448.     $showLocalhost = true;
  449. }
  450.  
  451. $displayedGraph='connections';
  452. @setlocale(LC_TIME , cfCaption('_ISO_639'));
  453.  
  454.  
  455. /*
  456.  ***************************************************************************************************************************
  457.  * Content thumbnails (from tooltip or viewed files list)
  458.  ***************************************************************************************************************************
  459.  */
  460. if(isset($_GET['thumbnail']) && isset($_GET['contentId'])){
  461.     $completeFilename=sqlite_single_query($db,"SELECT content FROM contentAccess WHERE id='".sqlite_escape_string($_GET['contentId'])."'");
  462.     require_once(INCLUDE_DIR.'explorerFunctions.php');
  463.  
  464.     // Limit size
  465.     if(!isset($_GET['w']))$_GET['w']=cfGGetVar('historyThumbnailsWidth'); $_GET['w']=min($_GET['w'],STATS_MAX_THUMBNAIL_WIDTH);
  466.     if(!isset($_GET['h']))$_GET['h']=cfGGetVar('historyThumbnailsHeight');; $_GET['h']=min($_GET['h'],STATS_MAX_THUMBNAIL_HEIGHT);
  467.  
  468.     // Tooltip's thumbnail: don't cache (bug WA - don't know why some images got cached with another one's id)
  469.     if($_GET['w']>99) WHeaders::noCache(); else WHeaders::cache($completeFilename);
  470.  
  471.     // Images thumbnails
  472.     if(efFileType($completeFilename)=='image'){
  473.         header('Content-Type: image/jpeg');
  474.         cfCreateResizedJPG($completeFilename,0,0,'',$_GET['w'],$_GET['h'],false,90);
  475.     }
  476.  
  477.     // Videos thumbnails
  478.     if(efFileType($completeFilename)=='video'){
  479.         header('Content-Type: image/jpeg');
  480.         efMakeVideoThumbnail($completeFilename,'',$_GET['w'],$_GET['h'],90,10);
  481.     }
  482.     exit;
  483. }
  484.  
  485. //cfDbg($_POST);
  486. /*
  487.  ***************************************************************************************************************************
  488.  * Process POST AND GET ASYNC commands
  489.  *
  490.  * Format:
  491.  * - data2: extra data (depends on command)
  492.  * - data3: command (setLogViewedContent, setlogViewedContentDisplayThumbnails, monitorLastViewedFile, getFileInfo, shell, chatNow
  493.  * - data4: extra data (depends on command)
  494.  * - data5: tracked user's session id (user tracking) or graph type (stats: connections, visitors, resources)
  495.  ***************************************************************************************************************************
  496.  */
  497. if(cfIsAsync() && isset($_POST['data2']) && isset($_POST['data3'])){
  498.     // XML response header
  499.     cfAsyncHeader();
  500.  
  501.     // toggle historyLogViewedContent general value
  502.     if($_POST['data3']=='setLogViewedContent'){
  503.         if(cfIsInApp() || cfGGetVar('advancedAdministration')){
  504.             $historyLogViewedContent=($_POST['data2']=='true')?true:false;
  505.             cfGUpdateVar('historyLogViewedContent',$historyLogViewedContent);
  506.             sleep(1);
  507.         }
  508.         // Reload page for single user tracking
  509.         if($displayType=='history') echo cfAsyncXMLJSaction('wl.goURL()');
  510.     }
  511.  
  512.     // toggle logViewedContentDisplayThumbnails general value
  513.     elseif($_POST['data3']=='setlogViewedContentDisplayThumbnails'){
  514.         if(cfIsInApp() || cfGGetVar('advancedAdministration')){
  515.             $logViewedContentDisplayThumbnails=($_POST['data2']=='true')?true:false;
  516.             cfGUpdateVar('logViewedContentDisplayThumbnails',$logViewedContentDisplayThumbnails);
  517.         }
  518.     }
  519.  
  520.     // Last viewed file information (single history, left panel)
  521.     elseif($_POST['data3']=='monitorLastViewedFile'){
  522.         // Last async updated content id (-1 on 1st async update)
  523.         $lastViewedContentId=$_POST['data4'];
  524.  
  525.         // Get all viewed resource
  526.         $query='SELECT resourceId FROM resAccess WHERE connectionId = '.sqlite_escape_string($_POST['data2']);
  527.         
  528.         foreach (sqlite_array_query($query,$db,SQLITE_ASSOC) as $resId){
  529.             $rc=new WResConfig($resId['resourceId']);
  530.             if(!$rc->isValid()) continue;
  531.             // Insert new resources or reorder resources
  532.             echo cfAsyncXMLJSaction('historyAsyncInsertResource("'.$rc->id().'","'.$rc->icon16().'","'.addslashes(cfUTF8Encode($rc->name())).'")');
  533.         }
  534.         
  535.         // If viewed files are not logged (and not displayed), just update resources access, not last viewed file
  536.         if(!cfGGetVar('historyLogViewedContent')) die(cfAsyncFooter());
  537.         
  538.         // Get last viewed file
  539.         $query='SELECT id,resourceId,content,ts FROM contentAccess WHERE connectionId = '.sqlite_escape_string($_POST['data2']).' AND content!="" ORDER BY ts DESC';
  540.         $res=sqlite_array_query($query,$db,SQLITE_ASSOC);
  541.  
  542.         // If not any content viewed, set lastViewedContentId to 0 (!=-1) so list will be updated
  543.         if(!count($res) && $lastViewedContentId==-1) echo cfAsyncXMLJSaction('lastViewedContentId=0');
  544.  
  545.         // If any found
  546.         if(count($res)){
  547.             $contentId=$res[0]['id'];
  548.             $resourceId=$res[0]['resourceId'];
  549.             $completeFilename=$res[0]['content'];
  550.             $content=''; $title='';
  551.  
  552.  
  553.             /**
  554.              * If new content ($_POST['data4'] contains last viewed content's id, or -1 if first async request after sync refresh)
  555.              */
  556.             if($contentId!=$lastViewedContentId){
  557.                 /**
  558.                  * Last viewed file thumbnail
  559.                  */
  560.  
  561.                 // Title
  562.                 $title='<div class="frame2Header">'.cfCaption('historyLastViewedFile').'</div><br><div class="historyContentList" style="cursor:pointer;white-space:nowrap;overflow:hidden" onclick="shell(this)" alt="'.$contentId.'" title="'.cfUTF8Encode($completeFilename).'">'.cfUTF8Encode(basename($completeFilename)).'</div>';
  563.  
  564.  
  565.                 // Thumbnail/content
  566.                 if(is_file($completeFilename)){
  567.                     require_once(INCLUDE_DIR.'explorerFunctions.php');
  568.                     require(INCLUDE_DIR.'fileInfoFunctions.php');
  569.  
  570.                     // Set path to computerRoot to access all files
  571.                     $prevPath=cfRGetVar('path'); cfRSetVar('path','computerRoot');
  572.                     $fi=fiGetInfo($completeFilename,true,true);
  573.                     if(!isset($fi['thumbnailURLW'])) $fi['thumbnailURLW']=STATS_MAX_THUMBNAIL_WIDTH;
  574.                     if(!isset($fi['thumbnailURLH'])) $fi['thumbnailURLH']=STATS_MAX_THUMBNAIL_HEIGHT;
  575.  
  576.                     // Image or video: display thumbnail
  577.                     if(efFileType($completeFilename)=='image' || efFileType($completeFilename)=='video'){
  578.                         $src='/local/showHistory.php?thumbnail=1&contentId='.$contentId.'&w='.$fi['thumbnailURLW'].'&h='.$fi['thumbnailURLH'];
  579.                         $content='<center style="margin-top:0.3em"><div class="photoFrame"><img alt="" src="'.$src.'" style="width:'.$fi['thumbnailURLW'].'px;height:'.$fi['thumbnailURLH'].'px"></div></center>';
  580.                     }
  581.  
  582.                     // Other file types:
  583.                     else{
  584.                         if(isset($fi['thumbnailURL']) && substr($fi['thumbnailURL'],0,5)=='code:'){
  585.                             $content=substr($fi['thumbnailURL'],5);
  586.                         }
  587.                         elseif(isset($fi['extra'])){
  588.                             foreach ($fi['extra'] as $v) if(isset($v['c']) && isset($v['v']) && $v['c'] && $v['v']) $content.='<b>'.($v['c']).cfCaption('genSeparator').'</b> '.cfUTF8Encode($v['v']).'<br>';
  589.                         }
  590.                         if($content) $content='<div class="frame3">'.$content.'</div>';
  591.                     }
  592.  
  593.                     // Restore path
  594.                     cfRSetVar('path',$prevPath);
  595.                 }
  596.  
  597.                 echo cfAsyncXMLInnerHTMLbyId($title.$content,'lvfTN');
  598.                 echo cfAsyncXMLJSaction('lastViewedContentId="'.$contentId.'"');
  599.  
  600.                 /**
  601.                  * Update history list
  602.                  */
  603.                 // Skip if first display
  604.                 if($lastViewedContentId!=-1){
  605.  
  606.                     // Get resources and accounts id/name correspondance
  607.                     $resources=array(); foreach (sqlite_array_query($db,'SELECT * FROM resource',SQLITE_ASSOC) as $value) $resources[$value['id']]=$value['name'];
  608.                     $accounts=array();  foreach (sqlite_array_query($db,'SELECT * FROM account',SQLITE_ASSOC)  as $value) $accounts[$value['id']] =$value['name'];
  609.                     $resourcesConfigs=cfResourcesGetAll();
  610.  
  611.                     // Go to last non-displayed resources/contents
  612.                     for($i=1;$i<count($res);$i++) if($res[$i]['id']==$lastViewedContentId) break;
  613.                     // Time-reverse browse updated non-displayed resources/contents
  614.                     for($i--;$i>=0;$i--){
  615.                         // New resource
  616.                         if(!isset($res[$i+1]) || $res[$i]['resourceId']!=$res[$i+1]['resourceId']){
  617.                             $resourceId=$res[$i]['resourceId'];
  618.                             // Resource icon
  619.                             if(isset($resourcesConfigs[$resourceId])) $iconSrc=$resourcesConfigs[$resourceId]['resourceIcon'];
  620.                             else $iconSrc=outIcon('broken');
  621.                             // Resource name
  622.                             $resourceName=cfUTF8Encode($resources[$resourceId]);
  623.                             // Update script
  624.                             echo cfAsyncXMLJSaction('historyAsyncInsertResource("'.$resourceId.'","'.$iconSrc.'","'.$resourceName.'",1)');
  625.                         }
  626.                         // New content
  627.                         // icon
  628.                         if(is_file($completeFilename)){
  629.                             // If has thumbnail, send 'tn' as icon src. Actual src will be built by js, from id
  630.                             if(efFileType($completeFilename)=='image' || efFileType($completeFilename)=='video') $iconSrc='tn';
  631.                             else $iconSrc=efIcon($completeFilename);
  632.                         }
  633.                         else $iconSrc='false';
  634.                         echo cfAsyncXMLJSaction('historyAsyncInsertContent("'.$res[$i]['id'].'","'.$iconSrc.'","'.cfUTF8Encode($res[$i]['content']).'","'.date(cfcaption('_HMS_DATE_FORMAT'),$res[$i]['ts']).'")');
  635.                     }
  636.                 }
  637.             }
  638.         }
  639.     }
  640.  
  641.     // Tooltip
  642.     elseif($_POST['data3']=='getFileInfo'){
  643.         require_once(INCLUDE_DIR.'explorerFunctions.php');
  644.         require(INCLUDE_DIR.'fileInfoFunctions.php');
  645.  
  646.         // Get source filename from content id
  647.         $completeFilename=sqlite_single_query($db,"SELECT content FROM contentAccess WHERE id='".sqlite_escape_string($_POST['data2'])."'");
  648.  
  649.         // Create a resource context so fiGetInfo can be used
  650.         if(!isset($_SESSION['activeResourceId'])) cfRCreateFakeResource();
  651.  
  652.         // Set path to computerRoot to access all files
  653.         $prevPath=cfRGetVar('path'); cfRSetVar('path','computerRoot');
  654.  
  655.         switch (efFileType($completeFilename)){
  656.             // Image or video: just display thumbnail
  657.             case 'image':
  658.             case 'video':
  659.                 // Show thumbnail in tooltip
  660.                 $fi=fiGetInfo($completeFilename,true,false);
  661.                 $fi['thumbnailURL']='/local/showHistory.php?thumbnail=1&contentId='.$_POST['data2'].'&w='.$fi['thumbnailURLW'].'&h='.$fi['thumbnailURLH'];
  662.                 unset($fi['footer']);
  663.                 unset($fi['cTime']);
  664.                 unset($fi['mTime']);
  665.  
  666.                 echo cfAsyncXMLJSaction('tooltipSetProperties('.fiPHPArrayToJSArray($fi).')');
  667.                 break;
  668.             // Not an image or video file: use regular tooltip methods
  669.             default:
  670.                 // Get file info tooltip content
  671.                 if(is_file($completeFilename))
  672.                     echo cfAsyncXMLJSaction('tooltipSetProperties('.fiPHPArrayToJSArray(fiGetInfo($completeFilename,false,true)).')');
  673.                 else
  674.                     echo cfAsyncXMLJSaction('tooltipDestroy()');
  675.         }
  676.  
  677.         // Restore path
  678.         cfRSetVar('path',$prevPath);
  679.     }
  680.     // shell: open viewed file on local computer
  681.     elseif($_POST['data3']=='shell' && $_SERVER['REMOTE_ADDR']=='127.0.0.1'){
  682.         // Get source filename from content id
  683.         $completeFilename=sqlite_single_query($db,"SELECT content FROM contentAccess WHERE id='".sqlite_escape_string($_POST['data2'])."'");
  684.         // View viewable file
  685.         require_once(INCLUDE_DIR.'explorerFunctions.php');
  686.         $ft=efFileType($completeFilename);
  687.         $fe=cfFileExtension($completeFilename);
  688.         if($ft=='text' || $ft=='audio' || $ft=='video' || $ft=='image' || $fe=='pdf' || $fe=='doc' || $fe=='ppt' || $fe=='xls');
  689.         else $completeFilename=dirname($completeFilename);
  690.  
  691.         win_shell_execute($completeFilename,'open');
  692.         //customExecFork('explorer','SW_SHOWNORMAL','"'.str_replace('/','\\',$completeFilename).'"');
  693.     }
  694.     // Chat with user
  695.     elseif($_POST['data3']=='chatNow' && $_SERVER['REMOTE_ADDR']=='127.0.0.1' && is_file(cfAppDataDir().'/'.$_POST['data2'])){
  696.         cfServerSendCmd('showChatWindow',array('resourceConfigFilename'=>$_POST['data2'],'destSessionId'=>$_POST['data4']));
  697.     }
  698.  
  699.     // Disconnected user ?
  700. //    cfDbg($displayType.$infoType,1);
  701.     if($displayType=='history' && $_POST['data5'] && $_POST['data5']!='null' && !file_exists(cfAppDataDir().'/sessionData/sess_'.$_POST['data5'])){
  702.         $usersConfigs=cfMGetVar('weezoUsers');
  703.         $userId=sqlite_single_query($db,'SELECT accountId FROM connection WHERE id="'.sqlite_escape_string($_POST['data2']).'"');
  704.         echo cfAsyncXMLJSaction('setDisconnected("'.str_replace('"','',cfCaption('chatDisconnected',cfUTF8Encode($usersConfigs[$userId]['name']))).'")');
  705.     }
  706.  
  707.     die(cfAsyncFooter());
  708. }
  709.  
  710. /*
  711.  ***************************************************************************************************************************
  712.  * Process POST AND GET SYNC commands
  713.  ***************************************************************************************************************************
  714.  */
  715. if(isset($_POST['data3']) && isset($_POST['data4'])){
  716.     parse_str($_POST['data4'],$data);
  717.     if(isset($data['infoType'])) $infoType=$data['infoType'];
  718.     if(isset($data['showLocalhost']) && $data['showLocalhost']=='true') {$showLocalhost=true;cfRSetVar('showLocalhost',true);}
  719.     if(isset($data['showLocalhost']) && $data['showLocalhost']=='false') {$showLocalhost=false;cfRSetVar('showLocalhost',false);}
  720.  
  721.     // Time interval
  722.     if(isset($data['selectedMonth']) && is_numeric($data['selectedMonth'])) $selectedMonth=$data['selectedMonth'];
  723.     if(isset($data['intStart']) && is_numeric($data['intStart'])) $intStart=$data['intStart'];
  724.     if(isset($data['intLength']) && is_numeric($data['intLength'])) $selectedMonth=$data['intLength'];
  725.     if($_POST['data3']=='setMonth' && is_numeric($_POST['data2'])){
  726.         $selectedMonth=$_POST['data2'];
  727.         $intStart=$_POST['data2'];
  728.         $intLength='month';
  729.     }
  730.     if($_POST['data3']=='intMonth' && is_numeric($_POST['data2'])){
  731.         $intStart=$_POST['data2'];
  732.         $intLength='month';
  733.     }
  734.     if($_POST['data3']=='intWeek' && is_numeric($_POST['data2'])){
  735.         $intStart=$_POST['data2'];
  736.         $intLength='week';
  737.     }
  738.     if($_POST['data3']=='intAll'){
  739.         $intStart=0;
  740.         $intLength='all';
  741.     }
  742.     // Stats: set info type (details or synth)
  743.     if($_POST['data3']=='setInfo'){
  744.         if($_POST['data2']=='details' || $_POST['data2']=='synth') $infoType=$_POST['data2'];
  745.     }
  746.     // Include/remove localhost connections from history/stats
  747.     if($_POST['data3']=='setLocalhost'){
  748.         if($_POST['data2']=='true') $showLocalhost=true; else $showLocalhost=false;
  749.         cfRSetVar('showLocalhost',$showLocalhost);
  750.     }
  751.     // Clear history/stats database
  752.     if($_POST['data3']=='clearHistory'){
  753.         if(cfIsInApp() || cfGGetVar('advancedAdministration')) {
  754.             dbCloseDB();
  755.             dbResetDB();
  756.             $db=dbOpenDB();
  757.         }
  758.     }
  759. }
  760. if(isset($_POST['data5']) && $_POST['data5']!='' && $_POST['data5']!='undefined') $displayedGraph=$_POST['data5'];
  761.  
  762. if(isset($_GET['graph']) && isset($_GET['intStart']) && isset($_GET['intEnd']) && isset($_GET['intLength']) && isset($_GET['showLocalhost']) && is_numeric($_GET['intStart']) && is_numeric($_GET['intEnd'])){
  763.     if($_GET['graph']=='Connections') drawConnections($_GET['intStart'], $_GET['intEnd'], isset($_GET['intLength']), $_GET['showLocalhost']);
  764.     if($_GET['graph']=='Visitors') drawVisitors($_GET['intStart'], $_GET['intEnd'], isset($_GET['intLength']), $_GET['showLocalhost']);
  765.     if($_GET['graph']=='Resources') drawResources($_GET['intStart'], $_GET['intEnd'], isset($_GET['intLength']), $_GET['showLocalhost']);
  766. }
  767.  
  768. // Set current month
  769. $sm=$selectedMonth;
  770. $firstConnection=sqlite_single_query($db,"SELECT min(ts) FROM connection");
  771.  
  772. if($intStart==0){
  773.     $intLength='all';
  774.     $intStart=$firstConnection;
  775.     $intEnd=time();
  776. }
  777. else{
  778. // Set interval end
  779.     switch ($intLength){
  780.         case 'day':
  781.             $intEnd=mktime(23,59,59,date('n',$intStart),date('j',$intStart),date('Y',$intStart));
  782.             break;
  783.         case 'week':
  784.             $length=6*24*3600; $length+=(date('h',$intStart)-date('h',$intStart+$length))*3600; // Compute week length including potential clock adjustment
  785.             $intEnd=mktime(23,59,59,date('n',$intStart+$length),date('j',$intStart+$length),date('Y',$intStart+$length));
  786.             break;
  787.         case 'month':
  788.             $intEnd=mktime(23,59,59,date('n',$intStart+(date('t',$intStart)-1)*24*3600),date('j',$intStart+(date('t',$intStart)-1)*24*3600),date('Y',$intStart+(date('t',$intStart)-1)*24*3600));
  789.             break;
  790.         default:
  791.             $intEnd=mktime(23,59,59,date('n',time()+6*24*3600),date('j',time()+6*24*3600),date('Y',time()+6*24*3600));
  792.     }
  793. }
  794.  
  795. /*
  796.  ***************************************************************************************************************************
  797.  * Javascript functions
  798.  ***************************************************************************************************************************
  799.  */
  800. ?>
  801. <script type="text/javascript">
  802. var lastViewedContentId=-1;
  803. function displayConnections(){
  804.     document.comForm.data5.value="connections";
  805.     dgi("selectedGraph").src=PHP_SELF+"?graph=Connections&intStart=<?php echo $intStart;?>&intEnd=<?php echo $intEnd;?>&intLength=<?php echo $intLength;?>&showLocalhost=<?php echo $showLocalhost;?>&noSt=true";
  806. }
  807. function displayVisitors(){
  808.     document.comForm.data5.value="visitors";
  809.     dgi("selectedGraph").src=PHP_SELF+"?graph=Visitors&intStart=<?php echo $intStart;?>&intEnd=<?php echo $intEnd;?>&intLength=<?php echo $intLength;?>&showLocalhost=<?php echo $showLocalhost;?>&noSt=true";
  810. }
  811. function displayResources(){
  812.     document.comForm.data5.value="resources";
  813.     dgi("selectedGraph").src=PHP_SELF+"?graph=Resources&intStart=<?php echo $intStart;?>&intEnd=<?php echo $intEnd;?>&intLength=<?php echo $intLength;?>&showLocalhost=<?php echo $showLocalhost;?>&noSt=true";
  814. }
  815. function monitorLastViewedFile(){
  816.     fas("<?php echo (isset($dbId))?$dbId:'-';?>",'monitorLastViewedFile',lastViewedContentId,"<?php echo (isset($_GET['sessionId']))?$_GET['sessionId']:'';?>",'async');
  817. }
  818.  
  819. var contentThumbnailsShown=<?php if(cfGGetVar('logViewedContentDisplayThumbnails')) echo 1; else echo 0; ?>;
  820. tooltipDelay=1;
  821.  
  822. function setMonth(ts){
  823.     fas(ts,'setMonth');
  824. }
  825. function intMonth(ts){
  826.     fas(ts,'intMonth');
  827. }
  828. function intWeek(ts){
  829.     fas(ts,'intWeek');
  830. }
  831. function intAll(ts){
  832.     fas(false,'intAll');
  833. }
  834. function setInfo(inf){
  835.     fas(inf,'setInfo');
  836. }
  837. function setLocalhost(lh){
  838.     if(lh) fas('true','setLocalhost'); else fas('false','setLocalhost')
  839. }
  840. function statsToggleCollapse(anim){
  841.     if(anim.step==0 && !anim.reverse) contentShowThumbnails(anim.item.id)
  842. }
  843. function clearHistory(){
  844.     if(confirm("<?php echo cfCaption('clearHistory');?>")) fas(true,'clearHistory');
  845. }
  846. function shell(val){
  847.     fas(val.alt,'shell',1,null,'async');
  848. }
  849. function chatNow(){
  850.     fas("<?php echo (isset($chatResourceFilename))?$chatResourceFilename:'-';?>",'chatNow',"<?php echo (isset($_GET['sessionId']))?$_GET['sessionId']:'-';?>",null,'async');
  851. }
  852. function setLogViewedContent(val){
  853.     fas((val?'true':'false'),'setLogViewedContent',1,null,'async');
  854. }
  855. function setlogViewedContentDisplayThumbnails(val){
  856.     contentThumbnailsShown=val;
  857.     fas((val?'true':'false'),'setlogViewedContentDisplayThumbnails',1,null,'async');
  858.     contentToggleThumbnails(val);
  859. }
  860. function contentToggleThumbnails(show){
  861.     var ctns=document.getElementsByName("ctn");
  862.     for(var i=0;i<ctns.length;i++){
  863.         if(show){
  864.             if(show && ctns[i].parentNode.parentNode.parentNode.parentNode.style.display!="none"){
  865.                 if(!ctns[i].src) ctns[i].src="<?php echo $_SERVER['SCRIPT_NAME']?>?thumbnail=1&contentId="+ctns[i].parentNode.alt
  866.                 ctns[i].style.display="inline";
  867.             }
  868.         }
  869.         else ctns[i].style.display="none";
  870.     }
  871. }
  872. function historyAsyncInsertResource(rId,iconSrc,resourceName,moveTop){
  873.     var iht='';
  874.     if(dgi('resFrame_'+rId)){
  875.         if(!moveTop) return;
  876.         iht=dgi('resFrame_'+rId).innerHTML;
  877.         removeNode(dgi('resFrame_'+rId));
  878.     }
  879.     
  880.     subNode=D.createElement('div');
  881.     subNode.id='resFrame_'+rId;
  882.     subNode.setAttribute('class','frame4');subNode.setAttribute('className','frame4');
  883.     subNode.innerHTML=(iht)?iht:'<div class="frame4Header"><img src="'+iconSrc+'" class="themeIcon">'+resourceName+'</div><div class="historyContent"></div>';
  884.     
  885.     if(dgi('connectionInnerFrame').firstChild)
  886.         dgi('connectionInnerFrame').insertBefore(subNode,dgi('connectionInnerFrame').firstChild);
  887.     else
  888.         dgi('connectionInnerFrame').appendChild(subNode);
  889. }
  890. function historyAsyncInsertContent(contentId,iconSrc,contentName,contentTs){
  891.     var tsNode=document.createElement('span');
  892.     tsNode.setAttribute('class','historyContentDate');tsNode.setAttribute('className','historyContentDate');
  893.     tsNode.innerHTML=contentTs;
  894.  
  895.     var subNode=document.createElement('li');
  896.     subNode.setAttribute('class','historyContentList');subNode.setAttribute('className','historyContentList');
  897.     subNode.setAttribute('alt',contentId);
  898.     subNode.setAttribute('onclick',function(){shell(this)});
  899.     subNode.setAttribute('onmouseover',function(){tooltip(this)});
  900.     var ih='';
  901.     if(iconSrc){
  902.         if(iconSrc=='tn'){
  903.             if(contentThumbnailsShown){
  904.                 ih+='<img name="ctn" class="ctn" alt="" style="display:inline;height:1px" onload="this.style.height=\'\'" src="<?php echo $_SERVER['SCRIPT_NAME']?>?thumbnail=1&contentId='+contentId+'">';
  905.             }
  906.             else
  907.                 ih+='<img name="ctn" class="ctn" alt="" src="<?php echo $_SERVER['SCRIPT_NAME']?>?thumbnail=1&contentId='+contentId+'">';
  908.         }
  909.         else ih+='<img name="ctn" class="ctn" alt="" src="'+iconSrc+'" onmouseover="tooltip(this)"'+((contentThumbnailsShown)?' style="display:inline"':'')+'>';
  910.     }
  911.     ih+=contentName;
  912.  
  913.     subNode.innerHTML=ih;
  914.     var par=dgi('connectionInnerFrame').firstChild.firstChild.nextSibling;
  915.     if(par.nodeType==1) {
  916.         par.insertBefore(subNode,par.firstChild);
  917.         par.insertBefore(tsNode,par.firstChild);
  918.     }
  919.     /*
  920.     else {
  921.         par=dgi('connectionInnerFrame').firstChild.firstChild.firstChild;
  922.     }
  923.     */
  924.  
  925.     //par.appendChild(subNode)}
  926.     //dgi('connectionInnerFrame').insertBefore(subNode,dgi('connectionInnerFrame').firstChild);
  927. }
  928.  
  929. function tooltipGetContent(nodeId){
  930.     fas(dgi(nodeId).alt,'getFileInfo',1,null,'async');
  931.     document.comForm.target='';
  932.     return '<img id="tooltipLoading" src="<?php echo outIcon('loading');?>">';
  933. }
  934. function contentShowThumbnails(connectionId){
  935.     if(!contentThumbnailsShown) return;
  936.     if(connectionId) connectionIdNode=dgi(connectionId);
  937.     var ctns=document.getElementsByName("ctn");
  938.     for(var i=0;i<ctns.length;i++){
  939.         if(!connectionId || ctns[i].parentNode.parentNode.parentNode.parentNode==connectionIdNode){
  940.             if(!ctns[i].src) {
  941.                 ctns[i].src="<?php echo $_SERVER['SCRIPT_NAME']?>?thumbnail=1&contentId="+ctns[i].parentNode.alt
  942.                 ctns[i].style.display="inline";
  943.             }
  944.             else ctns[i].style.display="inline";
  945.         }
  946.     }
  947. }
  948. var disconnected=0;
  949. function setDisconnected(capt){
  950.     if(disconnected) return;
  951.     disconnected=1;
  952.     var subNode=document.createElement('div');
  953.     subNode.setAttribute('class','warning');subNode.setAttribute('className','warning');
  954.     subNode.innerHTML=capt;
  955.     if(dgi('connectionInnerFrame').firstChild)
  956.         dgi('connectionInnerFrame').insertBefore(subNode,dgi('connectionInnerFrame').firstChild);
  957.     else
  958.         dgi('connectionInnerFrame').appendChild(subNode);
  959. }
  960. function init(){
  961.     contentShowThumbnails();
  962.     W.setInterval('monitorLastViewedFile()',<?php echo MONITOR_LAST_VIEWED_FILE_INTERVAL;?>);
  963.     monitorLastViewedFile();
  964.     resizeFrames();
  965. }
  966. function resizeFrames(){
  967.     var f2=dgi('rightFrame2');
  968.     if(W.winMe)    setActualHeight(f2,winMe.getInnerHeight()-5-actualOffsetTop(f2)-getElementStyle(f2,'margin-top',false)-getElementStyle(f2,'margin-bottom',false))
  969.     if(dgi('lvfTN')) setActualHeight(dgi('lvfTN'),f2.offsetHeight);
  970. }
  971. <?php if($infoType=='single') echo 'document.body.onload=init;';?>
  972. D.body.onresize=resizeFrames;
  973. </script>
  974. <style type="text/css">
  975. .ctn{vertical-align:middle;margin-right:0.3em;margin-bottom:2px;display:none}
  976. </style>
  977. <?php
  978. outInsertStandardComForm($_SERVER['PHP_SELF'],false,false,false,'infoType='.$infoType.'&intStart='.$intStart.'&intLength='.$intLength.'&selectedMonth='.$selectedMonth.'&showLocalhost='.(($showLocalhost)?'true':'false'),$displayedGraph);
  979.  
  980. /*
  981.  ***************************************************************************************************************************
  982.  * Display Tabs
  983.  ***************************************************************************************************************************
  984.  */
  985. echo outDivFrame('frame1');
  986.  
  987. /**
  988.  * Title
  989.  */
  990. if($displayType=='stats')
  991.     $l=outImage(outicon('stats'),false,false,'margin-right:1em').cfCaption('genStats');
  992. else
  993.     $l=outImage(outicon('log'),false,'class="themeIcon"').cfCaption('genHistory');
  994.  
  995. // Clear history
  996. if((cfIsInApp() || cfGGetVar('advancedAdministration')) && $infoType=='single'){
  997.     $r='<span>'.cfCaption('historyLogContent').'</span><input type="checkbox" onchange="setLogViewedContent(this.checked)" onclick="setLogViewedContent(this.checked)"'.((cfGGetVar('historyLogViewedContent'))?' checked="checked"':'').' style="margin-right:1em;margin-left:0.5em">';
  998.     $r.=cfCaption('bookmarksDisplayThumbnails').'<input type="checkbox" onchange="setlogViewedContentDisplayThumbnails(this.checked)" onclick="setlogViewedContentDisplayThumbnails(this.checked)"'.((cfGGetVar('logViewedContentDisplayThumbnails'))?' checked="checked"':'').' style="margin-left:0.5em">';
  999. }
  1000. elseif((cfIsInApp() || cfGGetVar('advancedAdministration')) && $infoType!='single')
  1001.     $r=outButton(cfCaption('clearHistory'),'javascript:clearHistory()',outIcon('cancel'));
  1002. else
  1003.     $r='';
  1004.  
  1005. echo outFrameHeaderTable("frame1Header",$l,$r);
  1006.  
  1007. // Frame used for left/right panels
  1008. echo outTableTransparent('frame1','table-layout:fixed');
  1009. echo "<tr>\n";
  1010.  
  1011. // Left panel
  1012. if($displayType=='stats' || $infoType=='list' || cfGGetVar('historyLogViewedContent')) echo "<td style=\"vertical-align:top;width:200px\">\n"; else echo "<td style=\"vertical-align:top\">\n";
  1013.  
  1014. /**
  1015.  * Last viewed file thumbnail
  1016.  */
  1017. if($infoType=='single' && cfGGetVar('historyLogViewedContent')) {
  1018.     echo outDivFrame('frame2',' id="lvfTN"');
  1019.     echo '<div class="frame2Header">'.cfCaption('historyLastViewedFile').'</div><br><div class="historyContentList" style="cursor:pointer;white-space:nowrap;overflow:hidden">-</div>';
  1020.     echo '<div class="frame3" style="height:120px"></div>';
  1021.     echo '</div>';
  1022. }
  1023.  
  1024. /*
  1025.  * Information selection
  1026.  */
  1027. if($displayType=='stats'){
  1028.     echo outDivFrame('frame2');
  1029.     echo '<div class="frame2Header">'.cfCaption('genInfos')."</div>\n";
  1030.     echo '<input type="radio" name="type" value="synth"'.(($infoType=='synth')?' checked="checked"':'').' onChange="setInfo(this.value)" onClick="setInfo(this.value)">'.cfCaption('calSynth').'<br />';
  1031.     echo '<input type="radio" name="type" value="details"'.(($infoType!='synth')?' checked="checked"':'').' onChange="setInfo(this.value)" onClick="setInfo(this.value)">'.cfCaption('genDetails');
  1032.     echo "</div>\n";
  1033. }
  1034.  
  1035.  
  1036. /*
  1037.  * Interval selection
  1038.  */
  1039. if($infoType!='single'){
  1040.     echo outDivFrame('frame2');
  1041.     echo '<div class="frame2Header">'.cfCaption('genInterval')."</div>\n";
  1042.         echo '<center>';
  1043.         @setlocale(LC_TIME, cfCaption('_ISO_639'));
  1044.         $firstDayOfMonth=mktime(0,0,1,date('n'),1,date('Y'));
  1045.         $day=$sm; while (date('w',$day)!=1) $day+=3600*24;
  1046.         $offset=(date('w',$sm)==0)?7:date('w',$sm);
  1047.  
  1048.         // Months drop box
  1049.         $month=mktime(0,0,1,date('n',$firstConnection),1,date('Y',$firstConnection));
  1050.         if($month!=$firstDayOfMonth){
  1051.             echo '<select name="selectMonth" id="selectMonth" size="1" onChange="setMonth(this.value)">'."\n";
  1052.             while ($month<=$firstDayOfMonth){
  1053.                 echo '<option value="'.$month.'"'.(($month==$sm)?' selected':'').'>'.cfUTF8Encode(ucfirst(strftime('%B %Y',$month))).'</option>';
  1054.                 if(date('n',$month)==12) $month=mktime(0,0,1,1,1,date('Y',$month)+1); else $month=mktime(0,0,1,date('n',$month)+1,1,date('Y',$month));
  1055.             }
  1056.             echo "</select><br/>\n";
  1057.         }
  1058.  
  1059.         // Calendar header
  1060.         echo '<table id="calendar" class="frame3" style="text-align:center;table-layout:fixed; cursor:pointer" cellspacing="0" cellpadding="0">';
  1061.         echo '<tr class="frame3Header" onmouseover="dgi(\'calendar\').style.background=\'#DDD\'" onmouseout="dgi(\'calendar\').style.background=\'\'" onclick="intMonth(\''.$sm.'\')">';
  1062.         for($i=0;$i<7;$i++) {echo '<td style="width:20px">'.cfUTF8Encode(strtoupper(substr(strftime('%A',$day),0,1))).'</td>'; $day+=3600*24;}
  1063.         echo '</tr><tr onmouseover="this.style.background=\'#DDD\'" onmouseout="this.style.background=\'\'" onclick="intWeek(\''.mktime(0,0,1,date('n',$sm-($offset-1)*24*3600),date('j',$sm-($offset-1)*24*3600),date('Y',$sm-($offset-1)*24*3600)).'\')">';
  1064.  
  1065.         // Calendar body (days)
  1066.         $day=$sm;
  1067.         for($i=1;$i<$offset;$i++) echo '<td> </td>';
  1068.         $position=$offset-1;
  1069.         for($i=1;$i<date('t',$sm)+1;$i++){
  1070.             if($position==7) {
  1071.                 $position=0;
  1072.                 if($firstDayOfMonth!=$sm || $i<=date('j')) echo '</tr><tr onmouseover="this.style.background=\'#DDD\'" onmouseout="this.style.background=\'\'" onclick="intWeek(\''.mktime(0,0,1,date('n',$sm),$i,date('Y',$sm)).'\')" style="">';
  1073.                 else echo '</tr><tr style="cursor:default">';
  1074.             }
  1075.             $position++;
  1076.             if($firstDayOfMonth!=$sm || $i<=date('j')){
  1077.                 echo '<td class="cell">'.$i.'</td>';
  1078.             }
  1079.             else echo '<td class="dcell">'.$i.'</td>';
  1080.         }
  1081.         echo '</tr></table>';
  1082.  
  1083.         // Current week button
  1084.         echo outButton(cfCaption('calCurrentWeek'),'javascript:intWeek(\''.mktime(0,0,1,date('n',time()-6*24*3600),date('j',time()-6*24*3600),date('Y',time()-6*24*3600)).'\')');
  1085.         echo '<br/>';
  1086.         // Total button
  1087.         echo outButton(cfCaption('genAll'),'javascript:intAll(\'\')');
  1088.         echo'<br>';
  1089.     echo "</center></div>\n";
  1090.  
  1091.     /*
  1092.      * Options
  1093.      */
  1094.     echo outDivFrame('frame2');
  1095.     echo '<div class="frame2Header">'.cfCaption('genOptions')."</div>\n";
  1096.     // Localhost connections
  1097.     echo '<input type="checkbox" onchange="setLocalhost(this.checked)" onclick="setLocalhost(this.checked)"'.((!$showLocalhost)?'':' checked="checked"').' style="margin-right:1em"><span style="position:absolute;width:150px;">'.cfCaption('calLocalhost').'</span><br/><br/>';
  1098.     // log content
  1099.     if($displayType=='history' && (cfIsInApp() || cfGGetVar('advancedAdministration'))){
  1100.         echo '<input type="checkbox" onchange="setLogViewedContent(this.checked)" onclick="setLogViewedContent(this.checked)"'.((cfGGetVar('historyLogViewedContent'))?' checked="checked"':'').' style="margin-right:1em"><span style="position:absolute;width:150px;">'.cfCaption('historyLogContent').'</span><br/><br/>';
  1101.         echo '<input type="checkbox" onchange="setlogViewedContentDisplayThumbnails(this.checked)" onclick="setlogViewedContentDisplayThumbnails(this.checked)"'.((cfGGetVar('logViewedContentDisplayThumbnails'))?' checked="checked"':'').' style="margin-right:1em">'.cfCaption('bookmarksDisplayThumbnails').'<br/>';
  1102.     }
  1103.  
  1104.  
  1105.     echo "</div>\n";
  1106.  
  1107.     // Close button
  1108.     if(cfIsInApp()) echo '<center><br/>'.outButton(cfCaption('genClose'),'javascript:wl.UICommand(\'close\')',outIcon('close')).'</center>';
  1109.  
  1110. }
  1111.  
  1112. // Close left panel
  1113. if($displayType=='stats' || $infoType=='list' || cfGGetVar('historyLogViewedContent')){
  1114.     echo '</td><td style="width:0.5em">';
  1115.     // Main frame td
  1116.     echo "<td style=\"vertical-align:top\">\n";
  1117. }
  1118.  
  1119. /*
  1120.  ***************************************************************************************************************************
  1121.  * RIGHT PANEL
  1122.  ***************************************************************************************************************************
  1123.  */
  1124. if($displayType=='history' && cfIsInApp())
  1125.     echo outDivFrame('frame2', 'id="rightFrame2"', 'height:415px;overflow:auto;white-space:nowrap');
  1126. else
  1127.     echo outDivFrame('frame2', 'id="rightFrame2"', 'height:400px;white-space:nowrap');
  1128.  
  1129. if($displayType=='stats') echo '<div class="frame2Header">'.cfCaption('calStatsFromTo',cfUTF8Encode(date(cfCaption('_DATE_FORMAT'),$intStart)),cfUTF8Encode(date(cfCaption('_DATE_FORMAT'),$intEnd)))."</div>\n";
  1130.  
  1131.  
  1132. /*
  1133.  ***************************************************************************************************************************
  1134.  * HISTORY
  1135.  ***************************************************************************************************************************
  1136.  */
  1137. if($displayType=='history' && $infoType=='list'){
  1138.     require_once(INCLUDE_DIR.'explorerFunctions.php');
  1139.  
  1140.     // Get resources and accounts id/name correspondance
  1141.     $resources=array(); foreach (sqlite_array_query($db,'SELECT * FROM resource',SQLITE_ASSOC) as $value) $resources[$value['id']]=$value['name'];
  1142.     $accounts=array();  foreach (sqlite_array_query($db,'SELECT * FROM account',SQLITE_ASSOC)  as $value) $accounts[$value['id']] =$value['name'];
  1143.     $resourcesConfigs=cfResourcesGetAll();
  1144.     $usersConfigs=cfMGetVar('weezoUsers');
  1145.  
  1146.  
  1147.     // Filter on date and localhost
  1148.     createViewHistory($intStart,$intEnd,$showLocalhost);
  1149.  
  1150.     // If content is logged and history is viewed by administrator or from application, include content
  1151.     if(cfGGetVar('historyLogViewedContent') && (cfIsInApp() || cfUGetVar('administrator'))){
  1152.         $result=sqlite_array_query($db,'SELECT baseView.id as id, baseView.ip as ip, baseView.pseudo as pseudo, baseView.ts as ts, baseView.accountId as accountId, baseView.totalDuration as totalDuration, baseView.resourceId as resourceId, contentAccess.id AS contentId, contentAccess.content AS content FROM baseView LEFT OUTER JOIN contentAccess ON baseView.id=contentAccess.connectionId AND baseView.resourceId=contentAccess.resourceId ORDER BY baseView.id DESC, baseView.resourceId ASC, contentAccess.ts DESC',SQLITE_ASSOC);
  1153.         $fullHistory=true;
  1154.     }
  1155.     // Else, show only basic info
  1156.     else{
  1157.         $result=sqlite_array_query($db,'SELECT * FROM baseView GROUP BY ip ORDER BY id DESC',SQLITE_ASSOC);
  1158.         $fullHistory=false;
  1159.     }
  1160.  
  1161.     $currentId=false;
  1162.     $currentResourceId=false;
  1163.     $hasContent=false;
  1164.     $firstConnection=true;
  1165.  
  1166.     foreach ($result as $k=>$record){
  1167.         // New connection
  1168.         if($record['id']!=$currentId){
  1169.             if($hasContent!==false) echo "</div>\n"; // Close content list
  1170.             if($currentResourceId!==false) echo "</div>\n"; // Close resource
  1171.             if($currentId!==false) {echo '</div></div><br>'; flush();} // Close connection
  1172.  
  1173.             $currentId=$record['id'];
  1174.             $currentResourceId=false;
  1175.             $hasContent=false;
  1176.  
  1177.             // Connection group
  1178.             echo outDivFrame('frame3');
  1179.  
  1180.             // New connection header and collapse button
  1181.             if(isset($usersConfigs[$record['accountId']])) $src='/gfx/icons/'.$usersConfigs[$record['accountId']]['icon'];
  1182.             else $src='/gfx/icons/blankIcon.gif';
  1183.             $l=' <img src="'.$src.'" class="themeIcon" alt="">';
  1184.             $l.=date(cfCaption('_FULL_DATE_FORMAT'),$record['ts']).'     ';
  1185.             $l.='<a href="http://'.$record['ip'].'" target="_blank" class="link">'.$record['ip'].'</a>     ';
  1186.             $l.='('.cfUTF8Encode($accounts[$record['accountId']]);
  1187.             if($record['pseudo']) $l.=' - '.cfUTF8Encode($record['pseudo']);
  1188.             $l.=')';
  1189.  
  1190.             if($record['resourceId']!='' || (isset($result[$k+1]) && $result[$k+1]['id']==$record['id']))
  1191.                 $r=outButtonToggleCollapse('cnxDiv'.$record['id'],false,false,'statsToggleCollapse');
  1192.             else
  1193.                 $r='';
  1194.             echo outFrameHeaderTable('frame3Header',$l,$r);
  1195.  
  1196.             // Total time
  1197.             if(($totalTime=$record['totalDuration'])){
  1198.                 $sec=$totalTime%60; $totalTime=floor($totalTime/60);
  1199.                 $min=$totalTime%60; $totalTime=floor($totalTime/60);
  1200.                 echo '<b>'.cfCaption('calTotalTime').cfCaption('genSeparator').'</b>'.cfCaption('calHourMinSec',cfUTF8Encode($totalTime),cfUTF8Encode($min), cfUTF8Encode($sec)).'<br/><br/>';
  1201.             }
  1202.  
  1203.             echo '<div id="cnxDiv'.$record['id'].'" style="display:none">';
  1204.             $firstConnection=false;
  1205.         }
  1206.  
  1207.         // New resource access
  1208.         if($record['resourceId']!=$currentResourceId){
  1209.             if($hasContent!==false) echo ' </div>'; // Close content list
  1210.             if($currentResourceId!==false) echo "</div>\n";
  1211.             $currentResourceId=$record['resourceId'];
  1212.             $hasContent=false;
  1213.             echo outDivFrame('frame4','id=resFrame_'.$currentResourceId).'<div class="frame4Header">';
  1214.  
  1215.             // Resource icon
  1216.             if(isset($resourcesConfigs[$currentResourceId])) $iconSrc=$resourcesConfigs[$currentResourceId]['definition']['resourceIcon'];
  1217.             else $iconSrc=outIcon('broken');
  1218.             echo outImage($iconSrc,false,'class="themeIcon"');
  1219.  
  1220.             // Resource name
  1221.             echo (isset($resources[$currentResourceId]))?cfUTF8Encode($resources[$currentResourceId]):'?';
  1222.             echo '</div>';
  1223.             if($fullHistory && $record['content']){
  1224.                 echo '<div class="historyContent">';
  1225.                 $hasContent=true;
  1226.             }
  1227.         }
  1228.  
  1229.         // New content
  1230.         if($fullHistory && $record['content']){
  1231.             if(!$hasContent) echo '<div class="historyContent">';
  1232.             $hasContent=true;
  1233.             echo '<li class="historyContentList"';
  1234.             if((cfIsInApp() && strpos($record['content'],'/')!==false)) {
  1235.                 echo ' onclick="shell(this)" alt="'.$record['contentId'].'" onmouseover="tooltip(this)">';
  1236.                 if(($ft=efFileType($record['content']))=='image' || $ft=='video')
  1237.                     echo '<img name="ctn" class="ctn" alt="">';
  1238.                 else
  1239.                     echo outImage(efIcon($record['content']),false,' name="ctn" class="ctn" onmouseover="tooltip(this)"');
  1240.  
  1241.             }
  1242.             else echo '>';
  1243.             echo cfUTF8Encode($record['content'])."</li>\n";
  1244.         }
  1245.     }
  1246.     if($hasContent!==false) echo "</div>\n"; // Close content list
  1247.     if($currentResourceId) echo "</div>\n"; // Close resource
  1248.     if($currentId) echo "</div>\n"; // Close connection
  1249. }
  1250.  
  1251.  
  1252. /*
  1253.  ***************************************************************************************************************************
  1254.  * SINGLE CONNECTED USER TRACKING
  1255.  ***************************************************************************************************************************
  1256.  */
  1257. if($displayType=='history' && $infoType=='single'){
  1258.     require_once(INCLUDE_DIR.'explorerFunctions.php');
  1259.  
  1260.     // Get resources and accounts id/name correspondance
  1261.     $resources=array(); foreach (sqlite_array_query($db,'SELECT * FROM resource',SQLITE_ASSOC) as $value) $resources[$value['id']]=$value['name'];
  1262.     $accounts=array();  foreach (sqlite_array_query($db,'SELECT * FROM account',SQLITE_ASSOC)  as $value) $accounts[$value['id']] =$value['name'];
  1263.     $resourcesConfigs=cfResourcesGetAll();
  1264.     $usersConfigs=cfMGetVar('weezoUsers');
  1265.  
  1266.  
  1267.     // Filter on connection id
  1268.     createViewDetail($dbId);
  1269.  
  1270.     // If content is logged and history is viewed by administrator or from application, include content
  1271.     if(cfGGetVar('historyLogViewedContent') && (cfIsInApp() || cfUGetVar('administrator'))){
  1272.         $result=sqlite_array_query($db,'SELECT baseView.id as id, baseView.ip as ip, baseView.pseudo as pseudo, baseView.ts as ts, baseView.accountId as accountId, baseView.resourceId as resourceId, contentAccess.id AS contentId, contentAccess.content AS content, contentAccess.ts as contentTs FROM baseView LEFT OUTER JOIN contentAccess ON baseView.id=contentAccess.connectionId AND baseView.resourceId=contentAccess.resourceId ORDER BY contentTs DESC',SQLITE_ASSOC);
  1273.         $fullHistory=true;
  1274.     }
  1275.     // Else, show only basic info
  1276.     else{
  1277.         $result=sqlite_array_query($db,'SELECT * FROM baseView GROUP BY ip ORDER BY id DESC',SQLITE_ASSOC);
  1278.         $fullHistory=false;
  1279.     }
  1280.  
  1281.     $currentId=false;
  1282.     $currentResourceId=false;
  1283.     $hasContent=false;
  1284.     $firstConnection=true;
  1285.  
  1286.     foreach ($result as $k=>$record){
  1287.         // New connection
  1288.         if($record['id']!=$currentId){
  1289.             $currentId=$record['id'];
  1290.             $currentResourceId=false;
  1291.             $hasContent=false;
  1292.  
  1293.             // New connection header and collapse button
  1294.             if(isset($usersConfigs[$record['accountId']])) $src='/gfx/icons/'.$usersConfigs[$record['accountId']]['icon'];
  1295.             else $src='/gfx/icons/blankIcon.gif';
  1296.             $l=' <img src="'.$src.'" class="themeIcon" alt="">';
  1297.             $l.=date(cfCaption('_FULL_DATE_FORMAT'),$record['ts']).'     ';
  1298.             $l.='<a href="http://'.$record['ip'].'" target="_blank" class="link">'.$record['ip'].'</a>     ';
  1299.             $l.='('.cfUTF8Encode($accounts[$record['accountId']]);
  1300.             if($record['pseudo']) $l.=' - '.cfUTF8Encode($record['pseudo']);
  1301.             $l.=')';
  1302.  
  1303.             $r='';
  1304.  
  1305.             // Chat button
  1306.             if(isset($chatResourceFilename)) $r.=' '.outButton(cfCaption('chatDoChat'),'javascript:chatNow()',outIcon('chat'));
  1307.  
  1308.             echo outFrameHeaderTable('frame3Header',$l,$r);
  1309.  
  1310.             echo '<div id="connectionInnerFrame">';
  1311.  
  1312.             // Total time
  1313.             if(isset($record['totalDuration']) && ($totalTime=$record['totalDuration'])){
  1314.                 $sec=$totalTime%60; $totalTime=floor($totalTime/60);
  1315.                 $min=$totalTime%60; $totalTime=floor($totalTime/60);
  1316.                 echo '<b>'.cfCaption('calTotalTime').cfCaption('genSeparator').'</b>'.cfCaption('calHourMinSec',cfUTF8Encode($totalTime),cfUTF8Encode($min), cfUTF8Encode($sec)).'<br/><br/>';
  1317.             }
  1318.  
  1319.             //echo '<div id="cnxDiv'.$record['id'].'" style="'.(($infoType=='single')?'':'display:none').'">';
  1320.             $firstConnection=false;
  1321.         }
  1322.  
  1323.         // New resource access
  1324.         if($record['resourceId']!=$currentResourceId){
  1325.             if($hasContent!==false) echo ' </div>'; // Close content list
  1326.             if($currentResourceId!==false) echo "</div>\n";
  1327.             $currentResourceId=$record['resourceId'];
  1328.             $hasContent=false;
  1329.             echo outDivFrame('frame4','id=resFrame_'.$currentResourceId).'<div class="frame4Header">';
  1330.             // Resource icon
  1331.             if(isset($resourcesConfigs[$currentResourceId])) $iconSrc=$resourcesConfigs[$currentResourceId]['definition']['resourceIconSmall'];
  1332.             else $iconSrc=outIcon('broken');
  1333.             echo outImage($iconSrc,false,'class="themeIcon"');
  1334.  
  1335.             // Respource name
  1336.             if(isset($resources[$currentResourceId])) echo cfUTF8Encode($resources[$currentResourceId]).'</div>';
  1337.             else echo '?</div>';
  1338.  
  1339.             if($fullHistory && $record['content']){
  1340.                 echo '<div class="historyContent">';
  1341.                 $hasContent=true;
  1342.             }
  1343.  
  1344.         }
  1345.  
  1346.         // New content
  1347.         if($fullHistory && $record['content']){
  1348.             if(!$hasContent) echo '<div class="historyContent">';
  1349.             $hasContent=true;
  1350.             echo '<span class="historyContentDate">'.date(cfCaption('_HMS_DATE_FORMAT'),$record['contentTs']).'</span>';
  1351.             echo '<li class="historyContentList"';
  1352.             if((cfIsInApp() && strpos($record['content'],'/')!==false)) {
  1353.                 echo ' onclick="shell(this)" alt="'.$record['contentId'].'" onmouseover="tooltip(this)">';
  1354.                 if(($ft=efFileType($record['content']))=='image' || $ft=='video')
  1355.                     echo '<img name="ctn" class="ctn" alt="">';
  1356.                 else
  1357.                     echo outImage(efIcon($record['content']),false,' name="ctn" class="ctn" onmouseover="tooltip(this)"');
  1358.  
  1359.             }
  1360.             else echo '>';
  1361.             echo cfUTF8Encode($record['content']);
  1362.             echo "</li>\n";
  1363.         }
  1364.     }
  1365.     if($hasContent!==false) echo "</div>\n"; // Close content list
  1366.     if($currentResourceId) echo "</div>\n"; // Close resource
  1367.     if($currentId) {
  1368.         echo outDivFrame('frame4',false,'padding:6px;margin-top:10px').outImageIcon('new').'<b>'.cfCaption('loginConnectButton').cfCaption('genSeparator').'</b>'.date(cfCaption('_FULL_DATE_FORMAT'),$record['ts']).'</div>';
  1369.         echo "</div>\n"; // connectionInnerFrame
  1370.     }
  1371. }
  1372.  
  1373.  
  1374. /*
  1375.  ***************************************************************************************************************************
  1376.  * STATISTICS GRAPHS
  1377.  ***************************************************************************************************************************
  1378.  */
  1379. elseif($infoType=='synth'){
  1380.     // Application window display
  1381.     if(isset($_ENV['configurationEnvironment']) && cfIsInApp()){
  1382.         echo '<center>';
  1383.         echo outButton(cfCaption('calBarPlotTitle'),'javascript:displayConnections()');
  1384.         echo outButton(cfCaption('calBarPieTitle'),'javascript:displayVisitors()');
  1385.         echo outButton(cfCaption('calResourcePieTitle'),'javascript:displayResources()').'<br/><br/>';
  1386.         // Graph
  1387.         if($displayedGraph=='connections') echo '<img alt="" id="selectedGraph" src="'.$_SERVER['PHP_SELF'].'?graph=Connections&intStart='.$intStart.'&intEnd='.$intEnd.'&intLength='.$intLength.'&showLocalhost='.$showLocalhost.'&noSt=true">';
  1388.         if($displayedGraph=='visitors') echo '<img alt="" id="selectedGraph" src="'.$_SERVER['PHP_SELF'].'?graph=Visitors&intStart='.$intStart.'&intEnd='.$intEnd.'&intLength='.$intLength.'&showLocalhost='.$showLocalhost.'&noSt=true">';
  1389.         if($displayedGraph=='resources') echo '<img alt="" id="selectedGraph" src="'.$_SERVER['PHP_SELF'].'?graph=Resources&intStart='.$intStart.'&intEnd='.$intEnd.'&intLength='.$intLength.'&showLocalhost='.$showLocalhost.'&noSt=true">';
  1390.         echo '</center>';
  1391.     }
  1392.     // Remote administration display
  1393.     else{
  1394.         // Connections
  1395.         echo '<img alt="" src="'.$_SERVER['PHP_SELF'].'?graph=Connections&intStart='.$intStart.'&intEnd='.$intEnd.'&intLength='.$intLength.'&showLocalhost='.$showLocalhost.'&noSt=true" width="400" height="350" style="vertical-align:middle; margin:0.5em; float:left">';
  1396.  
  1397.         // First time / returning Visitors
  1398.         echo '<img alt="" src="'.$_SERVER['PHP_SELF'].'?graph=Visitors&intStart='.$intStart.'&intEnd='.$intEnd.'&intLength='.$intLength.'&showLocalhost='.$showLocalhost.'&noSt=true" width="400" height="350" style="margin:0.5em">';
  1399.     echo '<br/>';
  1400.         // Resource access
  1401.         echo '<img alt="" src="'.$_SERVER['PHP_SELF'].'?graph=Resources&intStart='.$intStart.'&intEnd='.$intEnd.'&intLength='.$intLength.'&showLocalhost='.$showLocalhost.'&noSt=true" width="400" height="350" style="float:left; margin:0.5em">';
  1402.  
  1403.  
  1404.         // Misc text information
  1405.         echo '<div class="frame3" style="position:relative;height:342px;width:392px;margin:0.5em;left:5px;margin-left:0px">'; // (remove arbitrary 8px for padding + WA for left margin)
  1406.         createView2($intStart,$intEnd,$showLocalhost);
  1407.  
  1408.         echo '<div class="frame3Header">'.cfCaption('genMisc')."</div>\n";
  1409.         $nbUniques=count(sqlite_array_query($db,'SELECT ip,count(ip) FROM baseView GROUP BY ip',SQLITE_ASSOC));
  1410.         $totalTime=sqlite_single_query($db,'SELECT sum(duration) FROM baseView');
  1411.  
  1412.         // Unique visitors
  1413.         echo '<b>'.cfCaption('calUnique').cfCaption('genSeparator').'</b>'.cfUTF8Encode($nbUniques).'<br/><br/>';
  1414.  
  1415.         // Total connection time
  1416.         $sec=$totalTime%60; $totalTime=floor($totalTime/60);
  1417.         $min=$totalTime%60; $totalTime=floor($totalTime/60);
  1418.         echo '<b>'.cfCaption('calTotalTime').cfCaption('genSeparator').'</b>'.cfCaption('calHourMinSec',cfUTF8Encode($totalTime),cfUTF8Encode($min), cfUTF8Encode($sec)).'<br/>';
  1419.         // Debug
  1420.         //echo '<a target="_blank" href="http://localhost:8080'.$_SERVER['PHP_SELF'].'?graph=Visitors&intStart='.$intStart.'&intEnd='.$intEnd.'&intLength='.$intLength.'&showLocalhost='.$showLocalhost.'&noSt=true">Lien</a>';
  1421.         echo "</div>\n";
  1422.     }
  1423. }
  1424.  
  1425.  
  1426. /*
  1427.  ***************************************************************************************************************************
  1428.  * STATISTICS DETAILS
  1429.  ***************************************************************************************************************************
  1430.  */
  1431. elseif($infoType=='details'){
  1432.     createView1($intStart,$intEnd,$showLocalhost);
  1433.     $result=sqlite_array_query($db,'SELECT * FROM baseView GROUP BY ip ORDER BY ip,id DESC, ts ASC',SQLITE_ASSOC);
  1434.     $resources=array(); foreach (sqlite_array_query($db,'SELECT * FROM resource',SQLITE_ASSOC) as $value) $resources[$value['id']]=$value['name'];
  1435.     $accounts=array(); foreach (sqlite_array_query($db,'SELECT * FROM account',SQLITE_ASSOC) as $value) $accounts[$value['id']]=$value['name'];
  1436.  
  1437.     // Group by IP
  1438.     $list=array();
  1439.     foreach ($result as $value){
  1440.         if(!isset($list[$value['ip']])) $list[$value['ip']]=array();
  1441.         if(isset($value['hostname']) && strlen($value['hostname'])) $list[$value['ip']]['hostname']=$value['hostname'];
  1442.         if(!isset($list[$value['ip']][$value['id']])) $list[$value['ip']][$value['id']]=array('accountId'=>$value['accountId'],'totalDuration'=>$value['totalDuration'],'ts'=>$value['ts'],'res'=>array(),'pseudo'=>$value['pseudo']);
  1443.         if(!isset($list[$value['ip']][$value['id']]['res'][$value['resourceId']]) && $value['resourceId']!='') $list[$value['ip']][$value['id']]['res'][$value['resourceId']]=$value['nbPages'];
  1444.     }
  1445.     // IP group
  1446.     if(!count($list)) echo '<br/><br/><center>'.cfCaption('calNoConnection').'</center>';
  1447.     else{
  1448.         $ipNb=0;
  1449.         $resolvedIp=array();
  1450.         foreach ($list as $ip=>$ipGroup){
  1451.             // Resolve ip host name and store it into db
  1452.             if(!isset($ipGroup['hostname'])){
  1453.                 if(isset($resolvedIp[$ip])){
  1454.                     $hostName=$resolvedIp[$ip];
  1455.                 }
  1456.                 elseif($hostName=@gethostbyaddr($ip)){
  1457.                     sqlite_array_query($db,'UPDATE connection SET hostname=\''.str_replace('\'',"''",$hostName).'\' WHERE ip=\''.$ip.'\'');
  1458.                     $resolvedIp[$ip]=$hostName;
  1459.                 }
  1460.                 else {
  1461.                     $hostName='?';
  1462.                     sqlite_array_query($db,'UPDATE connection SET hostname=\''.str_replace('\'','`',$hostName).'\' WHERE ip=\''.$ip.'\'');
  1463.                     $resolvedIp[$ip]=$hostName;
  1464.                 }
  1465.             }
  1466.             else{
  1467.                 $hostName=$ipGroup['hostname'];
  1468.             }
  1469.             echo outDivFrame('frame2');
  1470.             echo outFrameHeaderTable('frame2Header','<a href="http://'.$ip.'" target="_blank">'.cfUTF8Encode($ip).' ('.cfUTF8Encode($hostName).')</a>',outButtonToggleCollapse('ipDiv'.$ipNb,false,false,'statsToggleCollapse'));
  1471.             echo '<div id="ipDiv'.$ipNb.'" style="display:none">';
  1472.             // Connection group
  1473.             $groupNb=0;
  1474.             foreach ($ipGroup as $id=>$connectionGroup) if($id!='hostname'){
  1475.                 echo outDivFrame('frame3');
  1476.                 echo outFrameHeaderTable('frame3Header',cfCaption('genGroup').cfCaption('genSeparator').cfUTF8Encode($accounts[$connectionGroup['accountId']]).((strlen($connectionGroup['pseudo']))?' - '.cfUTF8Encode($connectionGroup['pseudo']):''),date(cfCaption('_FULL_DATE_FORMAT'),$connectionGroup['ts']).' '.outButtonToggleCollapse('groupDiv'.$ipNb.'-'.$groupNb,false,((count($ipGroup)>3)?false:true),'statsToggleCollapse'));
  1477.                 echo '<div id="groupDiv'.$ipNb.'-'.$groupNb.'" style="display:'.((count($ipGroup)>3)?'none':'inline').'">';
  1478.                 $totalTime=$connectionGroup['totalDuration'];
  1479.                 $sec=$totalTime%60; $totalTime=floor($totalTime/60);
  1480.                 $min=$totalTime%60; $totalTime=floor($totalTime/60);
  1481.                 echo '<b>'.cfCaption('calTotalTime').cfCaption('genSeparator').'</b>'.cfCaption('calHourMinSec',cfUTF8Encode($totalTime),cfUTF8Encode($min), cfUTF8Encode($sec)).'<br/><br/>';
  1482.                 echo '<b>'.cfCaption('calResourceAccess').cfCaption('genSeparator').'</b><br/>';
  1483.                 // Resource access group
  1484.                 echo '<ul>';
  1485.                 if(count($connectionGroup['res'])>0){
  1486.                     foreach ($connectionGroup['res'] as $resourceId=>$nbPages){
  1487.                         echo '<li style="padding-left:1em">'.cfUTF8Encode((isset($resources[$resourceId]))?$resources[$resourceId]:'???').' ('.cfCaption('calResourcePieTitle').cfCaption('genSeparator').$nbPages.')</li>';
  1488.                     }
  1489.                 }
  1490.                 else echo '<li style="padding-left:1em">-</li>';
  1491.                 echo "</ul></div></div>\n";
  1492.                 $groupNb++;
  1493.             }
  1494.             echo "</div></div>\n";
  1495.             $ipNb++;
  1496.             flush();
  1497.         }
  1498.     }
  1499. }
  1500. echo "</div>";
  1501. echo "</td></tr></table></div>\n";
  1502.  
  1503. // Close DB
  1504. dbCloseDB();
  1505. ?>